home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Sample Code / Pascal Sample 3.0B10 / Source / Features.inc1.p next >
Encoding:
Text File  |  1993-10-13  |  6.6 KB  |  208 lines  |  [TEXT/MPS ]

  1. (******************************************************************************
  2. *
  3. *    Apple Macintosh Developer Technical Support
  4. *
  5. *    Code for the feature determination routines
  6. *
  7. *    Program:    Sample 3.0
  8. *    File:        Features.inc1.p - Pascal implementation
  9. *
  10. *    by:        Matt Deatherage
  11. *
  12. *    Copyright © 1988-1993 Apple Computer, Inc.
  13. *    All rights reserved.
  14. *
  15. *******************************************************************************
  16.  
  17. {$S Initialize}
  18. (******************************************************************************
  19. *
  20. * private: NumToolboxTraps
  21. *
  22. * This is straight out of Inside Macintosh (Volume VI, pages 3-8 and 3-9).
  23. * It checks to see if setting bit 9 of a toolbox trap (InitGraf, in this
  24. * case) makes a difference in what routine is called.  If it doesn't, there 
  25. * are $200 toolbox traps, but if it does, there are $400 traps.  Used by 
  26. * TrapAvailalble in this unit.
  27. ******************************************************************************)
  28.  
  29. FUNCTION NumToolboxTraps: INTEGER;
  30.  
  31. CONST
  32.     _InitGraf = $A86E;                { Trap number for the InitGraf trap }
  33.  
  34. BEGIN
  35.     IF NGetTrapAddress(_InitGraf, ToolTrap) = NGetTrapAddress($AA6E,
  36.        ToolTrap) THEN
  37.         NumToolboxTraps := $200
  38.     ELSE
  39.         NumToolboxTraps := $400;
  40. END; {NumToolboxTraps}
  41.  
  42. {$S Initialize}
  43. (******************************************************************************
  44. *
  45. * private: GetTrapType
  46. *
  47. * This is straight out of Inside Macintosh (Volume VI, pages 3-8 and 3-9).
  48. * It checks bit eight of a trap instruction to see if it's a Toolbox trap
  49. * or an OS trap.
  50. ******************************************************************************)
  51.  
  52. FUNCTION GetTrapType(theTrap: INTEGER): TrapType;
  53.  
  54. CONST
  55.     TrapMask = $0800;                { Only bit eight is significant }
  56.  
  57. BEGIN
  58.     IF BAND(theTrap, TrapMask) > 0 THEN
  59.         GetTrapType := ToolTrap
  60.     ELSE
  61.         GetTrapType := OSTrap;
  62. END; {GetTrapType}
  63.  
  64. {$S Initialize}
  65. (******************************************************************************
  66. *
  67. * private: TrapAvailable
  68. *
  69. * This is straight out of Inside Macintosh (Volume VI, pages 3-8 and 3-9).
  70. * It checks to see if a given trap is implemented.  The address in the
  71. * trap dispatch tables is compared against the address of the standard
  72. * Unimplemented trap.  If they're the same, the trap is unimplemented.  By
  73. * definition, the trap is also not implemented if it's a Toolbox trap but
  74. * beyond the end of the range of Toolbox traps.  The BOOLEAN result returns
  75. * whether or not the trap is implemented.
  76. ******************************************************************************)
  77.  
  78. FUNCTION TrapAvailable(theTrap: INTEGER): BOOLEAN;
  79.  
  80. CONST
  81.     _Unimplemented = $A89F;
  82.  
  83. VAR
  84.     tType: TrapType;                { the type of theTrap }
  85.  
  86. BEGIN
  87.     tType := GetTrapType(theTrap);
  88.     IF tType = ToolTrap THEN
  89.         BEGIN
  90.             theTrap := BAND(theTrap, $07FF);
  91.             IF theTrap >= NumToolboxTraps THEN
  92.                 theTrap := _Unimplemented;
  93.         END;
  94.     TrapAvailable := NGetTrapAddress(theTrap, tType) <>
  95.                      NGetTrapAddress(_Unimplemented, ToolTrap);
  96. END; {TrapAvailable}
  97.  
  98. {$S Initialize}
  99. (******************************************************************************
  100. *
  101. * Public: DetermineFeatures
  102. *
  103. * DetermineFeatures checks for all the features our application needs.  It
  104. * sets several global variables based on the results and returns TRUE if
  105. * the required features are implemented.  As written here, the only required
  106. * feature is having Gestalt implemented, which lets us check for all the
  107. * rest of the features we want to know about.
  108. *
  109. * Note that in many cases, the check for the _Gestalt trap is unnecessary.
  110. * MPW 3.2 and later link in glue code that always makes Gestalt available.
  111. * If you know your development environment does this, or if you are requiring
  112. * System 6.0.4 or later (highly recommended), you can remove the check for
  113. * Gestalt (as well as NumToolboxTraps, GetTrapType and TrapAvailable unless
  114. * you call them in another place, like we do when checking for DeviceLoop).
  115. * If you remove the calls, remember to set gHasGestalt to TRUE.
  116. ******************************************************************************)
  117.  
  118. FUNCTION DetermineFeatures: BOOLEAN;
  119.  
  120. CONST
  121.     _Gestalt = $A1AD;                { trap number for Gestalt }
  122.     _DeviceLoop = $ABCA;            { trap number for DeviceLoop }
  123.  
  124. VAR
  125.     featureErr: OSErr;                { error variable to use with Gestalt }
  126.     tempResult: LONGINT;            { temporary variable for Gestalt results }
  127.     tempBit: INTEGER;                { temporary variable for bit manipulation:
  128.                                       Pascal doesn't let you pass constants to
  129.                                       library routines like BTST }
  130.                                       
  131. BEGIN
  132.  
  133.     gHasGestalt := TrapAvailable(_Gestalt);
  134.     IF gHasGestalt THEN
  135.         BEGIN
  136.             
  137.             { Check for Balloon Help by testing for the Help Manager }
  138.             
  139.             tempBit := gestaltHelpMgrPresent;
  140.             featureErr := Gestalt(gestaltHelpMgrAttr, tempResult);
  141.             IF featureErr = noErr THEN
  142.                 gHasHelpMgr := BTst(tempResult, tempBit)
  143.             ELSE
  144.                 gHasHelpMgr := FALSE;
  145.  
  146.             { Check for color QuickDraw and 32-bit QuickDraw.  This is to work 
  147.               around a System 7 problem that occasionally makes Gestalt report
  148.               there's color QuickDraw when there isn't.  This method always
  149.               works.  }
  150.             
  151.             featureErr := Gestalt(gestaltQuickdrawVersion, tempResult);
  152.             gHasColorQD := FALSE;
  153.             gHas32BitQD := FALSE;
  154.             IF featureErr = noErr THEN
  155.                 BEGIN
  156.                     tempResult := BSR(tempResult, 8); { Shift the major version
  157.                                                        into the low byte }
  158.                     CASE tempResult OF
  159.                         1:
  160.                             gHasColorQD := TRUE;
  161.                         2:
  162.                             BEGIN
  163.                                 gHasColorQD := TRUE;
  164.                                 gHas32BitQD := TRUE;
  165.                             END;
  166.                     END;
  167.                 END;
  168.  
  169.             { Check for FindFolder.  Like with Gestalt, you can avoid this test
  170.               if you know your development environment provides glue for this
  171.               call like MPW 3.2 and later do. }
  172.             
  173.             gHasFindFolder := FALSE;
  174.             featureErr := Gestalt(gestaltFindFolderAttr, tempResult);
  175.             IF featureErr = noErr THEN
  176.                 gHasFindFolder := BTst(tempResult, gestaltFindFolderPresent);
  177.  
  178.             { Check for the DeviceLoop trap. }
  179.             
  180.             gHasDeviceLoop := TrapAvailable(_DeviceLoop);
  181.  
  182.             { Check for the Apple Events Manager.  You'll crash if you call it
  183.               when it's not implemented, such as under System 6.  }
  184.  
  185.             gHasAppleEvents := FALSE;
  186.             tempBit := gestaltAppleEventsPresent;
  187.             featureErr := Gestalt(gestaltAppleEventsAttr, tempResult);
  188.             IF featureErr = noErr THEN
  189.                 gHasAppleEvents := BTst(tempResult, tempBit);
  190.  
  191.             { Keep a copy of our application's resource file around.  Since we
  192.               call DetermineFeatures before doing any resource file 
  193.               manipulations, we're still the current resource file. }
  194.               
  195.               gAppsResourceFile := CurResFile;
  196.  
  197.             { Add more features here if you need them. }
  198.  
  199.         END; { if gHasGestalt then }
  200.  
  201.     DetermineFeatures := gHasGestalt; { We have no features if we have no Gestalt 
  202.                                         here. }
  203. END; {DetermineFeatures}
  204.